#include "gts_tools.h"
#include "utils.h"


bool  CGTSRead::Init()
{
  gts_file = fopen (gts_filename.c_str(), "r");
  s = gts_surface_new (gts_surface_class (),
		       gts_face_class (),
		       gts_edge_class (),
		       gts_vertex_class ());
  fp = gts_file_new (gts_file);
  if (gts_surface_read (s, fp)) {
    fputs ("volume: the file on standard input is not a valid GTS file\n", 
	   stderr);
    fprintf (stderr, "stdin:%d:%d: %s\n", fp->line, fp->pos, fp->error);
    return false; /* failure */
  }
  
  return true;
}

void  CGTSRead::IsPointsInside(GtsSurface * s)
{
  GtsPoint *p=gts_point_new(gts_point_class (),0,0,0);
  
  gts_surface_foreach_face (s, (GtsFunc) gts_triangle_revert, NULL);
  int ID;
  gboolean is_inside;

  GNode* bbTree=gts_bb_tree_surface (s);
  gboolean is_open=!gts_surface_is_closed (s);
  while (fscanf (id_file,"%lf %lf %lf %d", &p->x, &p->y, &p->z, &ID) == 4)
    {
      /*      gts_point_set(p, i, j, k);*/
      is_inside=gts_point_is_inside_surface(p,bbTree, is_open);
      if( is_inside)
	printf("%d\n", ID);
	//printf("%lf %lf %lf\n", p->x, p->y, p->z);
    }
  gts_object_destroy (GTS_OBJECT (p));
  gts_bb_tree_destroy(bbTree, true);
}
////////////////////////////
void  CGTSRead::IsOnePointInside(GtsSurface * s, gdouble x,gdouble y, gdouble z)
{
  GtsPoint *p=gts_point_new(gts_point_class (),x,y,z);
  
  gts_surface_foreach_face (s, (GtsFunc) gts_triangle_revert, NULL);
  //int ID;
  gboolean is_inside;

  GNode* bbTree=gts_bb_tree_surface (s);
  gboolean is_open=!gts_surface_is_closed (s);
      is_inside=gts_point_is_inside_surface(p,bbTree, is_open);
      if(is_inside)
	printf("1\n");
      else
	printf("0\n");
	
 
  gts_object_destroy (GTS_OBJECT (p));
  gts_bb_tree_destroy(bbTree, true);
}
////////////////////////////
//vector<int>  CGTSRead::GetPointsInside(GtsSurface * s, std::vector< tagCoord<float> > Pos)
vector<int>  CGTSRead::GetPointsInside(float *Pos, int np)
{
  vector<int> inside_index;
  int ind=0;
  GtsPoint *p=gts_point_new(gts_point_class (),0,0,0);
  
  gts_surface_foreach_face (s, (GtsFunc) gts_triangle_revert, NULL);

  gboolean is_inside;

  GNode* bbTree=gts_bb_tree_surface (s);
  gboolean is_open=!gts_surface_is_closed (s);

  for(int ind=0, i=0;ind<np;ind++)
    {
      i=ind*3;
      p->x=(gdouble)Pos[i];
      p->y=(gdouble)Pos[i+1];
      p->z=(gdouble)Pos[i+2];
      is_inside=gts_point_is_inside_surface(p,bbTree, is_open);
      if(is_inside)
	inside_index.push_back(ind);

    }	
 
  gts_object_destroy (GTS_OBJECT (p));
  gts_bb_tree_destroy(bbTree, true);
  return inside_index;
}

void CGTSRead::Stats()
{
  printf("\n## Printing Surface Statistics\n");
  GtsSurface * surface=s;
  gdouble threshold,  vol=0.0;
      {
	vol=gts_surface_volume (surface);
	gts_surface_print_stats (surface, stderr);
	fprintf (stderr, "# volume: %g area: %g\n", 
		 vol, gts_surface_area (surface));
      }
      printf("\n###########################\n");

}
void CGTSRead::ShowVertexes()
{
  guint nv = 1;
  gts_surface_foreach_vertex (s, (GtsFunc) write_vertex, &nv);
  
}
